package org.distributed.transaction.core.manager;

import java.lang.reflect.Method;

import org.distributed.transaction.core.connection.ProxyConnection;
import org.distributed.transaction.core.context.TccTransactionInfo;
import org.distributed.transaction.core.context.TransactionContext;
import org.distributed.transaction.core.context.TransactionStatus;
import org.distributed.transaction.core.context.TransactionUnit;
import org.distributed.transaction.core.enums.DTTransactionType;
import org.distributed.transaction.core.exception.TransactionException;
import org.distributed.transaction.core.repository.TransactionRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class DefaultTransactionManager implements TransactionManager {

	@Autowired
	private TransactionRepository transactionRepository;
	
	@Override
	public void begin(String groupId) throws TransactionException {
		transactionRepository.createGroup(groupId);
	}

	@Override
	public void join(TransactionContext transactionContext) throws TransactionException {
		transactionRepository.joinGroup(transactionContext.getGroupId(), new TransactionUnit());
	}

	@Override
	public void commit(TransactionContext transactionContext) throws TransactionException {
		if (DTTransactionType.Proxy.equals(transactionContext.getDtTransactionType())) {
			// 真的提交事务或者回滚事务
			ProxyConnection proxyConnection = (ProxyConnection) transactionContext
					.getConnection(transactionContext.getGroupId());
			proxyConnection.realExecute(transactionContext.getTransactionStatus());
		} else {
			TccTransactionInfo tccTransactionInfo = (TccTransactionInfo) transactionContext.getTransactionInfo();
			// Tcc 事务 提交/回滚 执行类
			Object executeClass = tccTransactionInfo.getExecuteClass();

			try {
				// 事务事务状态选择confirm和cancel
				Method executeMethod;
				if (TransactionStatus.CONFIRMING.equals(transactionContext.getTransactionStatus())) {
					executeMethod = executeClass.getClass().getMethod(tccTransactionInfo.getConfirmMethod(),
							tccTransactionInfo.getMethodTypeParameter());
				} else {
					executeMethod = executeClass.getClass().getMethod(tccTransactionInfo.getCancelMethod(),
							tccTransactionInfo.getMethodTypeParameter());
				}
				try {
					// 执行confirm或者cancel
					executeMethod.invoke(executeClass, tccTransactionInfo.getMethodParameter());
				} catch (Exception e) {
					e.printStackTrace();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public void rollback(TransactionContext transactionContext) throws TransactionException {
		commit(transactionContext);
	}
	

	@Override
	public void close(String groupId) {
		transactionRepository.clearGroup(groupId);
	}

	@Override
	public int getTransactionState(String groupId) {
		return 0;
	}

}
